﻿using Lhz.InternetService;
using Lhz.Sc.Business;
using Lhz.Sc.Entity.Database;
using Lhz.Sc.Entity.Exception;
using Lhz.Sc.Entity.Interface;
using Lhz.Sc.Interface;
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Web;

namespace Lhz.Sc.Service
{
    public class ServiceServiceCenter : IServiceCenterService
    {
        private ServiceInvoker ServiceInvoker
        {
            get
            {
                var si = HttpContext.Current.Application[ServiceInvokerSessionKey] as ServiceInvoker;
                if (si == null)
                {
                    si = new ServiceInvoker(typeof(InvokeArgument), typeof(InvokeResult));
                    HttpContext.Current.Application[ServiceInvokerSessionKey] = si;
                }
                return si;
            }
        }

        private const string UserSessionKey = "User";
        private const string ServiceInvokerSessionKey = "ServiceInvoker";

        private ServiceCenterOperation sco;

        public ServiceServiceCenter()
        {
            sco = new ServiceCenterOperation(ServiceInvoker);
        }

        public void Login(string username, string password)
        {
            sco.Login(username, password, (user) =>
            {
                HttpContext.Current.Session[UserSessionKey] = user;
            });
        }

        private string GetClientIp()
        {
            var context = OperationContext.Current;
            var properties = context.IncomingMessageProperties;
            return (properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty).Address;
        }

        private User GetLoginUser()
        {
            var user = HttpContext.Current.Session[UserSessionKey] as User;
            if (user == null)
            {
                throw new SessionNotFoundException();
            }
            return user;
        }

        public InvokeResult InvokeByJsonInvokeArgument(InvokeArgument invokeArgument)
        {
            return sco.JsonInvoke(invokeArgument, GetLoginUser(), GetClientIp());
        }

        public InvokeResult[] InvokeByJsonInvokeArguments(InvokeArgument[] invokeArguments)
        {
            return sco.JsonInvoke(GetLoginUser(), GetClientIp(), invokeArguments);
        }

        public Guid GetGuid()
        {
            return sco.GetGuid();
        }

        public Guid[] GetGuids(int count)
        {
            return sco.GetGuids(count);
        }
    }
}
